/*
 *  SyncIT , easy synchronization of files between computers and devices.
 *  Copyright (C) 2011  Christian Masus <cmasus(at)gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version. If redistributing and/or modifying
 *  this file, this notice must be included in the redistributed or
 *  modified copy.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package config;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

/**
 * Handles the storing and retrieval of the permanent stored configurations.
 * @author Christian Masus
 *
 */
public class PermanentStorage {

	private final boolean DEBUG = false;

	public static final String CONFIG_FILE = "config.ini";

	private String configPath;
	private String configFile;


	public PermanentStorage() {
		this.configPath = getDefaultConfigPath();
	}

	public PermanentStorage(String configPath) {
		this.configPath = configPath;
	}

	/**
	 * Initiates recourses for this PermanentStorage class.
	 * @return true if old configurations are found, false if new configurations has to be initiated.
	 */
	public boolean init() {
		this.configFile = configPath + File.separator + CONFIG_FILE;
		File configDir = new File(configPath);
		if(!configDir.exists()) {
			configDir.mkdirs();
		}
		File configF = new File(configFile);
		if(configF.exists() && configF.isFile()) {
			return true;
		}
		return false;
	}


	public String getConfigPath() {
		return configPath;
	}

	public void setConfigPath(String configPath) {
		this.configPath = configPath;
	}


	private OutputStreamWriter openOutBuffer() throws UnsupportedEncodingException, FileNotFoundException {
		return new OutputStreamWriter(new FileOutputStream(configFile, false), "UTF-8");
	}

	private BufferedReader openInBuffer() throws UnsupportedEncodingException, FileNotFoundException {
		return new BufferedReader(new InputStreamReader(new FileInputStream(configFile), "UTF-8"));
	}

	private void closeOutBuffer(OutputStreamWriter out) throws IOException {
		out.flush();
		out.close();
	}

	private void closeInBuffer(BufferedReader in) throws IOException {
		in.close();
	}


	private String getDefaultConfigPath() {
		String path = "";
		try {
			path = System.getProperty("user.home");
		}
		catch(SecurityException e) {
			if(DEBUG) System.err.println("Could not find the home directory");
			return (new File(".syncit")).getAbsolutePath();
		}

		if(path == null || path.equals("")) {
			if(DEBUG) System.err.println("Unknown error, fallback to default config path and file");
			return (new File(".syncit")).getAbsolutePath();
		}

		String os;
		try {
			os = System.getProperty("os.name").toUpperCase();
		}
		catch(SecurityException e) {
			if(DEBUG) System.err.println("Could not get OS information");
			os = "UNKNOWN";
		}

		// Windows
		if(os.indexOf("WIN") >= 0) {
			if( (new File(path + File.separator + "AppData" + File.separator + "Roaming")).exists() ) { // Windows Vista, 7 etc.
				path += File.separator + "AppData" + File.separator + "Roaming" + File.separator + "SyncIT";
			}
			else if( (new File(path + File.separator + "Application Data")).exists() ) { // Windows XP etc.
				path += File.separator + "Application Data" + File.separator + "SyncIT";
			}
			else { // Other Windows and local translations of Windows
				path += File.separator + "SyncIT";
			}
		}
		// Mac
		else if(os.indexOf("MAC") >= 0) {
			if( (new File(path + File.separator + "Library" + File.separator + "Application Support")).exists() ) { // Mac OS X 10.5 Leopard etc.
				path += File.separator + "Library" + File.separator + "Application Support" + File.separator + "SyncIT";
			}
			else {
				path +=  File.separator + ".syncit";
			}
		}
		// Linux and others Unix systems, etc
		else {
			path += File.separator + ".syncit";
		}
		return path;
	}




	public boolean storeConfig(String conf) {
		try {
			OutputStreamWriter out = openOutBuffer();
			out.write(conf);
			closeOutBuffer(out);
			return true;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	public String[] loadConfig() {
		ArrayList<String> configStrs = new ArrayList<String>();
		try {
			BufferedReader in = openInBuffer();
			String line = "";
			while((line = in.readLine()) != null) {
				configStrs.add(line);
			}
			closeInBuffer(in);
			return configStrs.toArray(new String[configStrs.size()]);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

}
